R Bootcamp day 3
Statistical Computing Track

George G. Vega Yon
vegayon@usc.edu
University of Southern California
Department of Preventive Medicine
August 21th, 2019
Before we start
You need to have Rcpp installed in your system:
You need to have a compiler
You can download the Rmd file here
R is great, but… (cont’d)
R has long time had an API (application programming interface) for integrating C/C++ code with R.
Unfortunately, it is not very straight forward
Enter Rcpp

Dirk Eddelbuettel and Romain François, lead authors of this R package
From the package description:
The ‘Rcpp’ package provides R functions as well as C++ classes which offer a seamless integration of R and C++
Example 1: Looping over a vector
## [1] 2 3 4 5 6 7 8 9 10 11
Example 1: Looping over a vector (vers 2)
Make it more sweet by adding some “sugar” (the Rcpp kind)
## [1] 2 3 4 5 6 7 8 9 10 11
How much fast?
Compared to this:
## Unit: relative
## expr min lq mean median uq max
## add1R(1:1000) 20.75614 10.51367 7.518645 9.265191 8.701998 6.132308
## add1Cpp(1:1000) 1.00000 1.00000 1.000000 1.000000 1.000000 1.000000
## neval cld
## 100 a
## 100 a
Main differences between R and C++
One is compiled and the other interpreted
Indexing objects: In C++ the indices range from 0 to (n - 1), whereas in R is from 1 to n.
All expressions end with a ; (this is optional in R).
In C++ object need to be declared, in R not (dynamic).
C++/Rcpp fundamentals: Types
Besides of the C-like types (double, int, char, and bool), we can use the following types of objects with Rcpp:
Matrices: NumericMatrix, IntegerMatrix, LogicalMatrix, CharacterMatrix
Vectors: NumericVector, IntegerVector, LogicalVector, CharacterVector
And more!: DataFrame, List, Function, Environment
C++/Rcpp fundamentals: Parts of “an Rcpp program”

Line by line, we see the following:
The #include<Rcpp.h> is similar to library(...) in R, it brings in all that we need to write C++ code for Rcpp.
using namespace Rcpp is somewhat similar to detach(...). This simplifies syntax. If we don’t include this, all calls to Rcpp members need to be explicit, e.g. instead of typing NumericVector, we would need to type Rcpp::NumericVector
The // starts a comment in C++, in this case, // [[Rcpp::export]] comment is a flag that Rcpp uses to “export” this C++ function to R.
Is the first part of the function definition. We are creating a function that returns a NumericVector, is called add1, has a single input element named x that is also a NumericVector.
C++/Rcpp fundamentals: Parts of “an Rcpp program” (cont’d)

Here we are declaring an object called ans which is a NumericVector with initial size equal to the size of x. Notice that .size() is called a “member function” of the x object, which is of class NumericVector.
We are declaring a for-loop. This has three parts:
int i = 0 We declare the variable i, an integer, and initialize it at 0.
i < x.size() This loop will end when i’s value is at or above the length of x.
++i At each iteration, i will increment in one unit.
ans[i] = x[i] + 1 set the i-th element of ans equal to the i-th element of x plus 1.
return ans exists the function returning the vector ans.
C++/Rcpp fundamentals (cont’d 2)
Now, where to execute/run this?
- You can use the
sourceCpp function from the Rcpp package to run .cpp scripts (this is what I do most of the time).
- There’s also the
cppFunction that allows you especifying a function.
- Write an R package that works with Rcpp.
For now, let’s just use the first option.
Example running .cpp file
Imagine that we have the following file named norm.cpp
We can compile and obtain this function using this line Rcpp::sourceCpp("norm.cpp"). Once compiled, a function called normRcpp will be available in the current R session.
Now, get ready for some Rcpp action!

Problem 1: Adding vectors
- Using what you have just learned about Rcpp, write a function to add two vectors of the same length. Use the following template
```cpp
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector add_vectors([declare vector 1], [declare vector 2]) {
... magick ...
return [something];
}
```
- Now, we have to check for lengths. Use the
stop function to see how can you return with an error if the two vectors don’t match size. Add the following lines in your code
```cpp
if ([some condition])
stop("an arbitrary error message :)");
```
Problem 2: Fibonacci series

- Each element of the sequence is determined by the following:
$$
F(n) = \left\{\begin{array}{ll}
n, & \mbox{ if }n \leq 1\\
F(n - 1) + F(n - 2), & \mbox{otherwise}
\end{array}\right.
$$
- Using recursions, we can implement this algorith in R as follows:
```r
fibR <- function(n) {
if (n <= 1)
return(n)
fibR(n - 1) + fibR(n - 2)
}
# Is it working?
c(fibR(0), fibR(1), fibR(2), fibR(3), fibR(4), fibR(5), fibR(6))
```
```
## [1] 0 1 1 2 3 5 8
```
Now, let’s translate this code into Rcpp and see how much speed boost we get!
Problem 2: Fibonacci series (solution)
## Unit: relative
## expr min lq mean median uq max neval
## fibR(20) 255.6643 255.1015 185.4705 226.2118 219.0175 12.76038 100
## fibCpp(20) 1.0000 1.0000 1.0000 1.0000 1.0000 1.00000 100
## cld
## b
## a
Thank you!
R Bootcamp day 3
Statistical Computing Track

Session info
## ─ Session info ──────────────────────────────────────────────────────────
## setting value
## version R version 3.6.1 (2019-07-05)
## os Ubuntu 16.04.6 LTS
## system x86_64, linux-gnu
## ui X11
## language en_US
## collate en_US.UTF-8
## ctype en_US.UTF-8
## tz America/Los_Angeles
## date 2019-08-21
##
## ─ Packages ──────────────────────────────────────────────────────────────
## package * version date lib source
## assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.5.3)
## backports 1.1.4 2019-04-10 [1] CRAN (R 3.6.0)
## callr 3.3.1 2019-07-18 [1] CRAN (R 3.6.1)
## cli 1.1.0 2019-03-19 [1] CRAN (R 3.5.3)
## codetools 0.2-16 2018-12-24 [3] CRAN (R 3.5.2)
## crayon 1.3.4 2017-09-16 [1] CRAN (R 3.4.1)
## desc 1.2.0 2018-05-01 [1] CRAN (R 3.4.4)
## devtools 2.1.0 2019-07-06 [1] CRAN (R 3.6.0)
## digest 0.6.20 2019-07-04 [1] CRAN (R 3.6.0)
## evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.0)
## fs 1.3.1 2019-05-06 [1] CRAN (R 3.6.0)
## glue 1.3.1 2019-03-12 [1] CRAN (R 3.5.3)
## htmltools 0.3.6 2017-04-28 [1] CRAN (R 3.5.1)
## knitr 1.24 2019-08-08 [1] CRAN (R 3.6.1)
## lattice 0.20-38 2018-11-04 [1] CRAN (R 3.5.1)
## magrittr 1.5 2014-11-22 [1] CRAN (R 3.5.1)
## MASS 7.3-51.4 2019-04-26 [3] CRAN (R 3.6.0)
## Matrix 1.2-17 2019-03-22 [3] CRAN (R 3.5.3)
## memoise 1.1.0 2017-04-21 [1] CRAN (R 3.4.0)
## microbenchmark 1.4-6 2018-10-18 [1] CRAN (R 3.5.1)
## multcomp 1.4-10 2019-03-05 [1] CRAN (R 3.5.3)
## mvtnorm 1.0-11 2019-06-19 [1] CRAN (R 3.6.0)
## pkgbuild 1.0.4 2019-08-05 [1] CRAN (R 3.6.1)
## pkgload 1.0.2 2018-10-29 [1] CRAN (R 3.5.1)
## prettyunits 1.0.2 2015-07-13 [1] CRAN (R 3.4.1)
## processx 3.4.1 2019-07-18 [1] CRAN (R 3.6.1)
## ps 1.3.0 2018-12-21 [1] CRAN (R 3.5.3)
## R6 2.4.0 2019-02-14 [1] CRAN (R 3.5.3)
## Rcpp 1.0.2 2019-07-25 [1] CRAN (R 3.6.1)
## remotes 2.1.0 2019-06-24 [1] CRAN (R 3.6.0)
## rlang 0.4.0 2019-06-25 [1] CRAN (R 3.6.0)
## rmarkdown 1.14 2019-07-12 [1] CRAN (R 3.6.1)
## rprojroot 1.3-2 2018-01-03 [1] CRAN (R 3.4.3)
## sandwich 2.5-1 2019-04-06 [1] CRAN (R 3.6.0)
## sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.5.1)
## stringi 1.4.3 2019-03-12 [1] CRAN (R 3.5.3)
## stringr 1.4.0 2019-02-10 [1] CRAN (R 3.5.3)
## survival 2.44-1.1 2019-04-01 [3] CRAN (R 3.5.3)
## testthat 2.2.1 2019-07-25 [1] CRAN (R 3.6.1)
## TH.data 1.0-10 2019-01-21 [1] CRAN (R 3.5.3)
## usethis 1.5.1.9000 2019-07-12 [1] Github (r-lib/usethis@c3ad943)
## withr 2.1.2 2018-03-15 [1] CRAN (R 3.4.3)
## xfun 0.9 2019-08-21 [1] CRAN (R 3.6.1)
## yaml 2.2.0 2018-07-25 [1] CRAN (R 3.5.1)
## zoo 1.8-6 2019-05-28 [1] CRAN (R 3.6.0)
##
## [1] /usr/local/lib/R/site-library
## [2] /usr/lib/R/site-library
## [3] /usr/lib/R/library